package org.ohos.rajawali3d.examples.examples.lights;

import ohos.agp.render.opengl.GLES20;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

import java.io.IOException;
import java.io.InputStream;
import java.nio.IntBuffer;

/**
 * Created by linchen on 2018/7/15.
 * mail: linchen@sogou-inc.com
 */
public abstract class GLESImpl {
    protected Context mContext;
    protected int mProgram;
    public static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "GLESImpl");

    public GLESImpl() {
        //initProgram();
    }

    public void initProgram() {
        int vertexShader = getVertexShader();
        int fragmentShader = getFragmentShader();

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram();

        // add the vertex shader to program
        GLES20.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES20.glAttachShader(mProgram, fragmentShader);

        bindShaders(mProgram);

//        GLES20.glBindAttribLocation(mProgram, 0, "a_Position");
//        GLES20.glBindAttribLocation(mProgram, 1, "a_Color");

        // creates OpenGL ES program executables
        GLES20.glLinkProgram(mProgram);
        final int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus);

        if (linkStatus[0] == 0) {
            GLES20.glDeleteProgram(mProgram);
            mProgram = 0;
        }
    }

    public void setContext(Context context) {
        mContext = context;
    }

    public static int loadShader(int type, String shaderCode) {

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, 1, new String[]{shaderCode}, IntBuffer.wrap(new int[]{shaderCode.length()}));
        GLES20.glCompileShader(shader);

        return shader;
    }

    public abstract void onDraw();

    public abstract void onSurfaceChange(int width, int height);

    protected abstract int getVertexShader();

    protected abstract int getFragmentShader();

    protected abstract void bindShaders(int program);

    public static PixelMap getPixelMapFromResource(Context context, int resourceId) {
        InputStream inputStream = null;
        try {
            // 创建图像数据源ImageSource对象
            inputStream = context.getResourceManager().getResource(resourceId);
            ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
            srcOpts.formatHint = "image/jpg";
            ImageSource imageSource = ImageSource.create(inputStream, srcOpts);
            // 设置图片参数
            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
            return imageSource.createPixelmap(decodingOptions);
        } catch (IOException e) {
            HiLog.info(LABEL_LOG, "IOException");
        } catch (NotExistException e) {
            HiLog.info(LABEL_LOG, "NotExistException");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    HiLog.info(LABEL_LOG, "inputStream IOException");
                }
            }
        }
        return null;
    }

    public float[] toFloat(double[] doubles) {
        float[] floats = new float[doubles.length];
        for (int i = 0; i < doubles.length; i++)
            floats[i] = (float) doubles[i];
        return floats;
    }
}
